Monografias.com > Sin categoría
Descargar Imprimir Comentar Ver trabajos relacionados

Programación basada en paso de mensajes (página 2)




Enviado por Pablo Turmero



Partes: 1, 2

Monografias.com

Opciones de programación
Diseño específico de un lenguaje: Occam ? Transputer
Extensión de lenguaje existente: Fortran M, CC++, Cilk++
www.netlib.org/fortran-m
www-unix.mcs.anl.gov/dbpp/text/node51.html
www.cilk.com
Biblioteca de paso de mensajes sobre C, Fortran, C++
PVM: www.csm.ornl.gov/pvm
MPI: www-unix.mcs.anl.gov/mpi
HPC++: www.extreme.indiana.edu/hpc++/index.html
Paralelización automática: El compilador extrae
paralelismo del código secuencial
¿ Sistema
Operativo ?
OpenMP

Monografias.com

(Gp:) 1979 Proyecto Europeo: Inmos SGS-Thomson ICL … †
(Gp:) Objetivo: µP de altas prestaciones, como elemento básico para
construir máquinas paralelas (multicomputadores)
(Gp:) 1992: habían vendido 500.000 unidades (µP+1MB => 180.000pts)
(Gp:) Característica relevante: 4 enlaces de comunicación (canales)

(Gp:) T800
(Gp:) 0
(Gp:) 1
(Gp:) 2
(Gp:) 3

Ejecución eficiente de n procesos que envían/reciben mensajes por canales
(Gp:) P1
(Gp:) P2
(Gp:) P3

Opciones … (TRANSPUTER)
(Gp:) cP3 ! dato
(Gp:) cP2 ? dato

Monografias.com

Creación de procesos
¿Cómo podría ser contarPar.c si no hay memoria común?
(Gp:) 1
(Gp:) 3
(Gp:) 2
(Gp:) 2
(Gp:) 6 2 0 …
(Gp:) 0 6 7 …
(Gp:) 6 2 5 …
(Gp:) 2 1 7 …
(Gp:) +
(Gp:) 8

(Gp:) esclavo1
(Gp:) esclavo2
(Gp:) esclavo3
(Gp:) esclavo4

(Gp:) maestro
(Gp:) 6 2 0 …
(Gp:) 0 6 7 …
(Gp:) 6 2 5 …
(Gp:) 2 1 7 …
(Gp:) El vector lo tiene un proceso “maestro”

El maestro: reparte “envía” trabajo a los “esclavos” y
recoge “recibe” resultados
(Gp:) 6 2 0 …
(Gp:) 0 6 7 …
(Gp:) 6 2 5 …
(Gp:) 2 1 7 …

(Gp:) 1
(Gp:) 3
(Gp:) 2
(Gp:) 2

(Gp:) 2 tipos distintos de procesos

Monografias.com

Creación de procesos
(Gp:) ¿Cómo podría ejecutarse la aplicación?
(Gp:) maestro
(Gp:) esclavo1
(Gp:) esclavo2
(Gp:) esclavoN

(Gp:) Un proceso x núcleo
(Gp:) M
(Gp:) E
(Gp:) E
(Gp:) E

Dos ejecutables: maestro.exe y esclavo.exe
(Gp:) maestro.c
(Gp:) esclavo.c
(Gp:) maestro.exe
(Gp:) esclavo.exe

(Gp:) Multiple Program Multiple Data
(Gp:) MPMD

(Gp:) maestro.exe
(Gp:) esclavo.exe

Creación de procesos: estática vs dinámica
¿Arquitecturas distintas?
¿ SPMD ?

Monografias.com

Creación de procesos (creación dinámica)
MPMD: Multiple Program Multiple Data
(Gp:) —————————
spawn (“esclavo”, 4, …)
—————————
(Gp:) maestro.c
(Gp:) —————————
contarEnTrozo (……)
—————————
(Gp:) esclavo.c

(Gp:) maestro

(Gp:) esclavo

(Gp:) %pvm
pvm>add PC2 …..
pvm>spawn maestro

M
(Gp:) E
(Gp:) E

Monografias.com

Creación de procesos (creación estática)
SPMD: Single Program Multiple Data
programa
fuente
(Gp:) *.exe
(Gp:) *.exe
(Gp:) *.exe

(Gp:) M
(Gp:) E

%mpirun –np 9 sort

%mpirun –p4pg
fiConf sort
(Gp:) —————————
if (miIdProceso == 0)
maestro()
else
esclavo()
—————————
(Gp:) sort.c

(Gp:) 0
(Gp:) 1
(Gp:) 8

Monografias.com

Creación de procesos
A veces, viene bien que el maestro también trabaje
(Gp:) esclavo1
(Gp:) esclavo2
(Gp:) esclavo3
(Gp:) maestro0
(Gp:) 6 2 0 …
(Gp:) 0 6 7 …
(Gp:) 6 2 5 …
(Gp:) 2 1 7 …
(Gp:) 0 6 7 …
(Gp:) 6 2 5 …
(Gp:) 2 1 7 …
(Gp:) 1
(Gp:) 3
(Gp:) 2
(Gp:) 2

Modelo SPMD y creación de procesos estática

Monografias.com

Rutinas genéricas de paso de mensajes
Pi.enviar(Pj, &msj, …) ? Pj.recibir(Pi, &msj, …)
(Gp:) —————————
enviar (esclavo,
&rodaja[k], …)
—————————
(Gp:) sortM
(Gp:) —————————
recibir (maestro,
&miRodaja, …)
—————————
(Gp:) sortE

(Gp:) Máquina
PID_Local

Varias semánticas:
Bloqueante (Síncrona | Rendezvous)
No bloqueante (Asíncrona: Capacidad de almacenar)
Temporizada (Tiempo máximo de bloqueo)
(Gp:) enviar( Pi, &msj, temporización, )
(Gp:) ?
(Gp:) 0
(Gp:) t

Monografias.com

Rutinas genéricas de paso de mensajes
Bloqueante vs NoBloqueante
(Gp:) ———-
———-
enviar…
———-
———-
(Gp:) ———-
———-
recibir…
———-
———-

(Gp:) El primero se bloquea

(Gp:) Transferencia sin buffers adicionales

(Gp:) Se sabe que se ha recibido

(Gp:) ———-
———-
enviar…
———-
———-
(Gp:) ———-
———-
recibir…
———-
———-
(Gp:) Buffer

(Gp:) Se desacopla env | rec

(Gp:) Gestión de buffers

(Gp:) ¿ Dónde ?

(Gp:) ¿Se ha recibido? => msjACK

enviar( Pi, &msj, temporización, …)

Monografias.com

Rutinas genéricas de paso de mensajes
recibirDeCualquiera (&msj) | recibir ( -1, &msj)
(Gp:) sortE1
(Gp:) sortEn
(Gp:) sortM

(Gp:) —————————
quien = recibir (-1,
&rodaja[k], …)
—————————
(Gp:) sortM

Mensajes etiquetados
P
P
P
P
P
P
P
H
(Gp:) enviar (S, &msj, tipoP)
enviar (S, &msj, tipoH)
(Gp:) recibir (-1, &msj, tipoH)

recibir (-1, &msj, -1 )
(Gp:) Cliente
(Gp:) Servidor
(Gp:) Cliente
(Gp:) Cliente

Monografias.com

Paso de mensajes entre “grupos”
Broadcast (a todos) Multicast (a unos concretos)
(Gp:) —————————
Para todo esclavo
enviar (esclavo,
&palabra, …)
—————————
(Gp:) cuentaM

Problema: Número de ocurrencias de (un dato)* en array grande
(Gp:) cuentaM
(Gp:) cuentaE1
(Gp:) cuentaEn
(Gp:) cuentaE2

(Gp:) “Ala”
(Gp:) “Ala”
(Gp:) “Ala”

(Gp:) —————————
bcast (esclavos,
&palabra, …)
—————————
(Gp:) cuentaM

¿Más eficiente?
¿Sincronismo?

Monografias.com

(Gp:) sortM

(Gp:)

sortE1
(Gp:)

sortEn
(Gp:) V

(Gp:) sortM

(Gp:)

sortE1
(Gp:)

sortEn
(Gp:) V

Paso de mensajes entre “grupos”
scatter ( esparcir ) y gather ( recoger ) Ej: Ordenación
(Gp:) scatter (V, rodaja, grupo, emisor, )
(Gp:) sortM y sortE

(Gp:) gather (V, rodaja, grupo, receptor, )
(Gp:) sortM y sortE

Monografias.com

Paso de mensajes entre “grupos”
int V[N];

inic(V);
i=0;
for (e=1; e< =nProc; e++) {
enviar (e, &V[i], longRodaja);
i += longRodaja;
}
ordenar (V, longRodaja);
i=0;
for (e=1; e< =nProc; e++) {
recibir(e, &V[i], longRodaja);
i += longRodaja;
}
int R[longRodaja];

recibir (0, R, longRodaja);
ordenar (V, longRodaja);
enviar (0, R, longRodaja);
int *V;

if (yo==0) { V = malloc(N); inic(V); }
else V = malloc(longRodaja);
scatter (V, V, grupo, 0);
ordenar (V, longRodaja);
gather (V, V, grupo, 0);

Monografias.com

(Gp:) cuentaM

(Gp:)

cuentaE1
(Gp:) 2
(Gp:) 3
(Gp:)

cuentaE2
(Gp:) 5
(Gp:)

cuentaEn
(Gp:) 1

Paso de mensajes entre “grupos”
reduce (recibir de unos concretos y operar) Ej: Ocurrencias
(Gp:) Total = veces;
Para todo esclavo
recibir (esclavo,
&veces, …)
Total += veces;
(Gp:) cuentaM

(Gp:) reduce (+, &veces, grupo, receptor, …)
(Gp:) cuentaM y cuentaE
(Gp:) +

(Gp:) máximo, mínimo, *, …..

¿Más eficiente?

Monografias.com

MPI (Introducción)
MPI: Message Passing Interface – 1994 MPI Forum [Nov/92]
“Ejecución de aplicaciones paralelas distribuidas en ordenadores heterogéneos”
(Gp:) maestro
(Gp:) esclavo1
(Gp:) esclavo3
(Gp:) esclavo2
(Gp:) esclavo4

Cada uno con su dirIP
Biblioteca “mpi.h”
MPI_Send,
MPI_Recv,
————-
(Gp:) M
(Gp:) E1
(Gp:) E2
(Gp:) E3
(Gp:) E4

Implementación
MPICH
LAM/MPI
IBM, …
MPI-2
MPI-3

Monografias.com

(Gp:) >= 0 => MPI_SUCCESS, significado concreto
< 0 => un error ( … MPI_ERR_ARG …)

MPI (Procesos)
(Gp:) int MPI_Comm_size(…, int *numProcesos);
(Gp:) int MPI_Comm_rank(…, int *yo);
(Gp:) int MPI_Finalize();
(Gp:) int MPI_Init( ……. ); /* Inicia MPI */

Creación estática de procesos (según implementación “mpirun”)
(Gp:) 0
(Gp:) 1
(Gp:) 3
(Gp:) 2
(Gp:) 4
(Gp:) MPI_COMM_WORLD

2
(Gp:) 5

(Gp:) 2

Monografias.com

MPI (Procesos)
(Gp:) helloWorld paralelo
(Gp:) #include “mpi.h”
int main (int argc,
char *argv[]) {
int yo, numProcesos;

MPI_Init (&argc, &argv);
MPI_Comm_size (MPI_COMM_WORLD, &numProcesos);
MPI_Comm_rank (MPI_COMM_WORLD, &yo);
if (yo == 0) printf (“Creados %d procesosn”, numProcesos);
printf (“Hola, soy el proceso %dn”, yo);
MPI_Finalize();
}

% mpirun –np 3 helloWorld
% mpirun –p4pg helloWorld.txt helloWorld
(Gp:) pc1 2 /usuarios/alumnosPropar/propar01/p1/helloWorld
pc2 2 /usuarios/alumnosPropar/propar01/p1/helloWorld
pc3 1 /usuarios/alumnosPropar/propar01/p1/holaMundo

Monografias.com

MPI (Envío y Recepción Simple)
Enviar y recibir arrays de datos simples (int, byte, …) Bloqueante

int vector[N];
———-
MPI_Send (vector, …
P2, …)
———-
P1

int tabla[M];
———-
MPI_Recv (tabla, …
P1, …)
———-
P2
int MPI_Send(void *buffer, int cuantos, MPI_Datatype tipo,
int destino, int etiqueta, MPI_Comm grupo)
(Gp:) MPI_INT,
MPI_FLOAT, …

(Gp:) MPI_COMM_WORLD
(Gp:) 0..MPI_TAG_UB

Monografias.com

MPI (Envío y Recepción Simple)
Enviar y recibir arrays de datos simples (int, byte, …) Bloqueante
int MPI_Recv(void *buffer, int cuantos, MPI_Datatype tipo,
int remitente,int etiqueta,MPI_Comm grupo,
MPI_Status *estado)
(Gp:) estado.MPI_SOURCE
estado.MPI_TAG

(Gp:) MPI_ANY_SOURCE

(Gp:) MPI_ANY_TAG

(Gp:) int MPI_Get_count( MPI_Status *estado, MPI_Datatype tipo,
int *cuantos)

Monografias.com

MPI (Envío y Recepción Simple)
Ejemplo de uso: psendrec.c
#include < stdio.h>
#include < unistd.h>

#include “mpi.h"

#define N 3
#define VECES 5

void esclavo(void) {…}
void maestro(void) {…}

int main( int argc, char *argv[] ) {
int yo;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &yo);
if (yo == 0) maestro();
else esclavo();
MPI_Finalize();
return 0;
}

Monografias.com

MPI (Envío y Recepción Simple)
Ejemplo de uso: psendrec.c
void maestro (void) {

int i, j, vector[N];

for (i=0; i< VECES; i++) {
printf ("M: envia => ");
for (j=0; j< N; j++) {
vector[j] = i*N+j;
printf("%d ", vector[j]);
}
printf ("n");
MPI_Send (vector, N, MPI_INT, 1, 1, MPI_COMM_WORLD);
}
}
(Gp:) esclavo

Monografias.com

MPI (Envío y Recepción Simple)
Ejemplo de uso: psendrec.c
void esclavo(void) {

int i, j,tabla[N], n;
MPI_Status estado;

sleep(2);
for (i=0; i< VECES; i++) {
MPI_Recv (tabla, N, MPI_INT, 0, 1,
MPI_COMM_WORLD, &estado);
MPI_Get_count (&estado, MPI_INT, &n);
printf ("E: recibe => ");
for (j=0; j< N; j++) printf("%d ", tabla[j]);
printf (" de tid = %d eti = %d longi = %dn",
estado.MPI_SOURCE, estado.MPI_TAG, n);
}
}
(Gp:) maestro

Monografias.com

MPI (Envío y Recepción No Tan Simple)
int MPI_Iprobe(int origen, int etiqueta, MPI_Comm grupo, int *hayMsj, MPI_Status *estado)
Enviar y recibir arrays de datos simples No Bloqueante
Enviar y recibir datos no homogéneos
Crear tipos => Algo tedioso
(Gp:) Hacer otras cosas
(Gp:) NO

(Gp:) int MPI_Recv(void *buffer,… MPI_Status *estado)
(Gp:) SI

Monografias.com

MPI (Comunicación colectiva)
int MPI_Bcast(void *buffer, int cuantos,
MPI_Datatype tipo, int emisor,
MPI_Comm grupo)
(Gp:) cuenta.0
(Gp:) cuenta.1
(Gp:) cuenta.N
(Gp:) cuenta.2
(Gp:) “Ala”
(Gp:) “Ala”
(Gp:) “Ala”

void maestro () { void esclavo () {
char palabra[4]; char texto[4];

———- ———-
MPI_Bcast ( MPI_Bcast (
palabra, 4, MPI_CHAR, texto, 4, MPI_CHAR,
0, MPI_COMM_WORLD); 0, MPI_COMM_WORLD);
———- ———-
(Gp:) ?
(Gp:) tag

(Gp:) Send+Recv

Monografias.com

MPI (Comunicación colectiva)
int MPI_Scatter(
void *vOrg, int nOrg, MPI_Datatype tOrg,
void *vDst, int nDst, MPI_Datatype tDst,
int emisor, MPI_Comm grupo);
(Gp:)

grupoE.1
(Gp:)

grupoE.9
(Gp:) grupoM.0

int MPI_Reduce(void *vOrg, void *vDst, int nOrg,
MPI_Datatype tDatoOrg, int operacion,
int receptor, MPI_Comm grupo);
(Gp:) +

(Gp:) MPI_SUM, MPI_PROD, MPI_MIN, MPI_MAX, ….

(Gp:) sendCount

Monografias.com

MPI (Comunicación colectiva: Ejemplo)
Ejemplo de uso completo: cuentaPar2.c (modelo SPMD)
#include < stdio.h>

#include “mpi.h"

#define CARDINALIDAD 2000000
#define MAX_ENTERO 1000
#define NUM_BUSCADO 5

int main( int argc, char *argv[] ) {

int i, numVeces, numVecesTotal, yo;
int longRodaja, numProcesos;
int *vector;

MPI_Init (&argc, &argv);
MPI_Comm_size (MPI_COMM_WORLD, &numProcesos);
MPI_Comm_rank (MPI_COMM_WORLD, &yo);
—————————
MPI_Finalize();
}

Monografias.com

MPI (Comunicación colectiva: Ejemplo)
Ejemplo de uso completo: cuentaPar2.c
// Pedir memoria vector e inicializarlo si maestro
longRodaja = CARDINALIDAD / numProcesos;
if (yo == 0) {
vector = malloc (CARDINALIDAD * 4);
for (i=0; i< CARDINALIDAD; i++)
vector[i] = random() % MAX_ENTERO;
} else
vector = malloc (longRodaja * 4);

MPI_Scatter (vector, longRodaja, MPI_INT,
vector, longRodaja, MPI_INT, 0, MPI_COMM_WORLD);
// Todos buscan en su trozo
numVeces = 0;
for (i=0; i< longRodaja; i++)
if (vector[i] == NUM_BUSCADO) numVeces++;
MPI_Reduce (&numVeces, &numVecesTotal, 1, MPI_INT,
MPI_SUM, 0 , MPI_COMM_WORLD);
if (yo == 0)
printf (“Numero de veces => %dn”, numVecesTotal);

Monografias.com

MPI (Comunicación colectiva)
Otras llamadas interesantes:
int MPI_Gather(void *vOrg, int nOrg, MPI_Datatype tOrg,
void *vDst, int nDst, MPI_Datatype tDst,
int receptor, MPI_Comm grupo);
int MPI_Barrier(MPI_Comm grupo);
———-
MPI_Comm_size (MPI_COMM_WORLD, &numProcesos);
———-
// Computar todos paso 1

MPI_Barrier (MPI_COMM_WORLD);

// Computar todos paso 2
(Gp:) 6

Monografias.com

Evaluación de programas paralelos
¿Cuánto tardará mi programa paralelo TP?
Medición experimental
Estudio analítico
(Gp:) Codificar, Depurar, Probar, …

(Gp:) Modelo imperfecto, aproximado

(Gp:) m
(Gp:) e0
(Gp:) e9
(Gp:) cuentaVeces:
V[1.000.000]
10 esclavos

(Gp:) TP = TCPU + TRED

(Gp:) Enviar rodajas TRED

(Gp:) Recibir veces TRED

(Gp:) Contar veces TCPU

(Gp:) veces = 0;
for (i=0; i< N’; i++)
if (rodaja[i] == D)
veces++;

(Gp:) N’
(Gp:) N

(Gp:) N’ * (#i * Tinst)

(Gp:) O (N)

| O (N2) | O (NlogN) | O(logN)

Monografias.com

Evaluación de programas paralelos
(Gp:) #m * (TL + #d * TD)

(Gp:) #d
(Gp:) t
(Gp:) TL

(Gp:) TP = TCPU + TRED
(Gp:) N’ * (#i * Tinst)

(Gp:) Ejemplos
(Gp:) T3D+PVM
(Gp:) IBM PS2+MPI
(Gp:) iacluster+MPI
(Gp:) 40?s
(Gp:) 35?s
(Gp:) 3?s
(Gp:) TL
(Gp:) 64ns
(Gp:) 230ns
(Gp:) 63ns
(Gp:) TD[8B]
(Gp:) 0,6ns
(Gp:) 4,2ns
(Gp:) 11ns
(Gp:) Tinst

(Gp:) 66666
(Gp:) 8333
(Gp:) 273
(Gp:) TL
(Gp:) 107
(Gp:) 55
(Gp:) 6
(Gp:) TD
(Gp:) 1
(Gp:) 1
(Gp:) 1
(Gp:) Tinst
(Gp:) Normalizar

(Gp:) TP = TCPU + TRED

(Gp:) Solapar tiempos | ocultar latencias
Comunicación asíncrona

(Gp:) #msj,
tamaño(#d),
topología red,
tecnología, …

Monografias.com

Evaluación de programas paralelos
Ejemplo: cuentaVeces, V[1.000.000], 10 esclavos
T1 = 1.000.000 * (#i * Tinst)
T10 = TRED(10Rodajas) + TCPU(100.000) + TRED(10Resultados)
(Gp:) T3D: TL(273) y TD(6)
(Gp:) T10 = 10*(273+100.000*6) + 100.000*#i*1 + 10*(273+6)
= 6.005.520 + 100.000#i

S10 = 1.000.000*#i / (6.005.520+100.000#i)

(Gp:) iacluster: TL(66.666) y TD(64)
(Gp:) T10 = … 66.666 … 64 + …*1 + … 66.666+64
= 65.333.960 + 100.000#i

S10 = 1.000.000*#i / (65.333.960 +100.000#i)

(Gp:) #i
(Gp:) S10
(Gp:) 50
(Gp:) 0,71
(Gp:) 100
(Gp:) 1,33
(Gp:) 500
(Gp:) 4,34

(Gp:) #i
(Gp:) S10
(Gp:) 5
(Gp:) 0,8
(Gp:) 10
(Gp:) 1,4
(Gp:) 500
(Gp:) 8,9

Monografias.com

Herramientas de depuración y monitorización
Medición de tiempos de ejecución
Depuración
Monitorización
(Gp:) #include < sys/time.h>

struct timeval t0, tf, tiempo;

/* Inicialización */

gettimeofday (&t0, NULL);

/* ejecucion del programa paralelo */

gettimeofday (&tf, NULL);
timersub (&tf, &t0, &tiempo);
printf (“Tiempo => %ld:%ld seg:micron”,
tiempo.tv_sec, tiempo.tv_usec);

(Gp:) Evitar E/S

¿Efecto del
optimizador
de código?
gcc –O3

Monografias.com

Herramientas de depuración y monitorización
(Gp:) %mpirun –dbg=ddd –np 2 psendrec

Depurar más de un proceso, algo más complejo
printf
fflush(stdout)
setbuf(stdout,
NULL)
(Gp:) depurar (ddd)

Monografias.com

Herramientas de depuración y monitorización
Monitorización (XPVM) para PVM

Monografias.com

Herramientas de depuración y monitorización
Monitorización (totalview) para MPI, openMP, … www.etnus.com
(Gp:) www.roguewave.com

Partes: 1, 2
 Página anterior Volver al principio del trabajoPágina siguiente 

Nota al lector: es posible que esta página no contenga todos los componentes del trabajo original (pies de página, avanzadas formulas matemáticas, esquemas o tablas complejas, etc.). Recuerde que para ver el trabajo en su versión original completa, puede descargarlo desde el menú superior.

Todos los documentos disponibles en este sitio expresan los puntos de vista de sus respectivos autores y no de Monografias.com. El objetivo de Monografias.com es poner el conocimiento a disposición de toda su comunidad. Queda bajo la responsabilidad de cada lector el eventual uso que se le de a esta información. Asimismo, es obligatoria la cita del autor del contenido y de Monografias.com como fuentes de información.

Categorias
Newsletter